/*
 * 文件名称: mic_eq_drc.c
 * 功能描述: EQ_DRC主要用来处理音效,主频160M，120个点,EQ和DRC算法时间分别为250us和180us左右;
 *           MIX_DRC主要用来一拖二音频混合,主频160M，120个点,算法时间为180us左右;
 ****************************************************************************************
 */
#include "include.h"
#include "mic_eq_drc.h"


#if WIRELESS_MIC_DRC_EN || ADAPTER_LOCAL_MIC_EQ_DRC_EN  || ADAPTER_MIC_DRC_EN

u16 mic_eq_buff[WIRELESS_MIC_SAMPLES_SELECT] AT(.eq_buf);

static drc_v3_cb_t eq_drc_cb;

static mic_eq_drc_cfg_t wireless_mic_eq_drc_cfg;

//------------------------------------------------------------------------------------------
//EQ_DRC处理

AT(.com_text.mic_eq_drc.input)
void mic_eq_drc_audio_input(u8 *ptr, u32 samples, int ch_mode, void *params)
{
    //硬件RQ
    if(wireless_mic_eq_drc_cfg.eq_en) {
        uint8_t nbyte = 2;
        mic_eq_proc((u16 *)ptr, mic_eq_buff, samples);
        memcpy(ptr, (u8 *)mic_eq_buff, samples*nbyte);
    }

    //软件数字增益和DRC处理
    if(wireless_mic_eq_drc_cfg.drc_en) {
        s32 sample = 0;
        u32 soft_gain = soft_gain_param_get();
        s16 *rptr = (s16 *)ptr;

        if(rptr) {
            for(int i = 0; i < samples; ++i) {
                sample = rptr[i];
                sample = __builtin_muls_shift15(sample, soft_gain);
                rptr[i] = drc_v3_calc(sample, &eq_drc_cb);
            }
        }
    }

    //输出到下一级
    if (wireless_mic_eq_drc_cfg.callback) {
        wireless_mic_eq_drc_cfg.callback(ptr, samples, ch_mode, params);
    }
}

AT(.text.mic_eq_drc.set)
void mic_eq_drc_audio_output_callback_set(audio_callback_t callback)
{
    wireless_mic_eq_drc_cfg.callback = callback;
}

AT(.text.mic_eq_drc.init)
void mic_eq_drc_init(u8 sample_rate, u16 samples)
{
    u32 eq_len, drc_len;
    u32 eq_addr, drc_addr;

    memset(&wireless_mic_eq_drc_cfg, 0, sizeof(wireless_mic_eq_drc_cfg));
    memset(&eq_drc_cb, 0, sizeof(eq_drc_cb));

    ///device和adapter使用不同的资源文件
    if(wireless_role_is_adapter()) {
        eq_len   = RES_LEN_ADPT_EQ_MIC_48K_EQ;
        eq_addr  = RES_BUF_ADPT_EQ_MIC_48K_EQ;
        drc_len  = RES_LEN_ADPT_EQ_MIC_48K_DRC;
        drc_addr = RES_BUF_ADPT_EQ_MIC_48K_DRC;
    } else {
        eq_len   = RES_LEN_DEV_EQ_MIC_48K_EQ;;
        eq_addr  = RES_BUF_DEV_EQ_MIC_48K_EQ;
        drc_len  = RES_LEN_DEV_EQ_MIC_48K_DRC;
        drc_addr = RES_BUF_DEV_EQ_MIC_48K_DRC;
    }

    if(mic_eq_set_by_res(eq_addr, eq_len)) {
        wireless_mic_eq_drc_cfg.eq_en = 1;      //使能EQ
    }

    if(mic_drc_set_by_res(drc_addr, drc_len, &eq_drc_cb)) {
        wireless_mic_eq_drc_cfg.drc_en = 1;     //使能DRC
    }
}

AT(.text.mic_eq_drc.exit)
void mic_eq_drc_exit(u8 sample_rate, u16 samples)
{
    wireless_mic_eq_drc_cfg.eq_en = 0;
    wireless_mic_eq_drc_cfg.drc_en = 0;
}
#endif

#if ADAPTER_MIX_DRC_EN
static drc_v3_cb_t mix_drc_cb;

//------------------------------------------------------------------------------------------
//MIX_DRC处理
//若output = NULL, MIX_DRC处理输出到pcm0
AT(.com_text.mix_drc.input)
void mix_drc_audio_input(s16 *pcm0, s16 *pcm1, s16 *output, u16 samples)
{
    s32 val = 0;
    s16 *out = (output == NULL)? pcm0 : output;

    for(uint i=0; i<samples; i++) {
        val = pcm0[i] + pcm1[i];
        out[i] = drc_v3_calc(val, &mix_drc_cb);
    }
}

AT(.text.mix_drc.init)
void mix_drc_init(void)
{
    memset(&mix_drc_cb, 0, sizeof(mix_drc_cb));

    drc_v3_init((const void *)RES_BUF_ADPT_EQ_MIX_48K_DRC, RES_LEN_ADPT_EQ_MIX_48K_DRC, &mix_drc_cb);
}

AT(.text.mix_drc.exit)
void mix_drc_exit(void)
{

}
#endif
